package com.itliuhouse.success.domain.dto;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itliuhouse.success.domain.vo.UserVO;
import com.itliuhouse.success.pojo.User;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

//分页返回的实体
@Data
@ApiModel(description = "分页结果")
@NoArgsConstructor
@AllArgsConstructor
public class PageDTO<T> {
    @ApiModelProperty("总条数")
    private Long total;
    @ApiModelProperty("总页数")
    private Long pages;
    @ApiModelProperty("数据集合")
    private List<T> list;

    //可以定义多个构造函数  这是因为不同的参数就是不同的构造对象

    /**
     * 返回空分页结果
     * @param p MybatisPlus的分页结果
     * @param <V> 目标VO类型
     * @param <P> 原始PO类型
     * @return VO的分页对象
     */
    public static <V , P> PageDTO<V> empty(Page<P> p){
        return new PageDTO<>(p.getTotal() , p.getPages() , Collections.emptyList());
    }

    /**
     *
     * 将MybatisPlus结果转化为VO分页结果
     * @param p MybatisPlus的分页结果
     * @param voClass 目标VO类型的字节码
     * @return VO的分页对象
     * @param <V> 目标的VO类型
     * @param <P> 原始的PO类型
     *
     *              List<User> records = page_info.getRecords();
     *         if(records == null || records.size() <= 0){
     *             //无数据,返回空结果 我知道 这样不能直接使用  因为data方法  只是set  和  get的方法
     *             //而无参构造和有参构造都会有对应的注解
     *             return new PageDTO<>(page_info.getTotal() , page_info.getPages() , Collections.emptyList());
     *         }
     *         //有数据 进行转化
     *         List<UserVO> voList = BeanUtil.copyToList(records, UserVO.class);
     *         //封装返回
     *         PageDTO<UserVO> pageDTO = new PageDTO<>(page_info.getTotal(), page_info.getPages(), voList);
     *
     */
    public static <V , P> PageDTO<V> of(Page<P> p , Class<V> voClass){
        //1.非空效验
        List<P> records = p.getRecords();
        if(records == null || records.size() == 0){
            //无数据 返回空结果
            return empty(p);
        }
        //2.数据转换
        //coClass 目标类型的字节码
        List<V> vos = BeanUtil.copyToList(records, voClass);
        //3.封装返回
        return new PageDTO<>(p.getTotal() ,p.getPages() ,vos);
    }


    /**
     * 将mybatisPlus分页结果为VO分页结果,允许用户自定义PO到VO的转换方式
     * @param p MybatisPlus的分页结果
     * @param convertor PO 到 VO 的转换函数
     * @return VO的分页对象
     * @param <V> 目标的VO类型
     * @param <P> 原始的PO类型
     */
    public static <V , P> PageDTO<V> of(Page<P> p , Function<P , V> convertor){
        //1.非空效验
        List<P> records = p.getRecords();
        if(records == null || records.size() <= 0){
            //无数据,返回空结果
            return empty(p);
        }
        //数据转换
        List<V> vos = records.stream().map(convertor).collect(Collectors.toList());
        //3.封装返回
        return new PageDTO<>(p.getTotal() , p.getPages() , vos);
    }


}
